package com.whsxt.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whsxt.constant.MenuConstant;
import com.whsxt.domain.SysMenu;
import com.whsxt.mapper.SysMenuMapper;
import com.whsxt.service.SysMenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * @Author: caoqingwen
 * @CreateTime: 2021-03-12 16:33
 * @Description: ${Description}
 */
@Service
@Slf4j
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {


    @Autowired
    private SysMenuMapper sysMenuMapper;


    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 加载菜单
     *
     * @param userId
     * @return
     */
    @Override
    public List<SysMenu> loadUserMenu(String userId) {
        log.info("加载树菜单");
        //从缓存里面拿
        String menuStr = redisTemplate.opsForValue().get(MenuConstant.MENU_PREFIX + userId);
        List<SysMenu> sysMenus = null;
        if (StringUtils.isEmpty(menuStr)) {
            //查询数据库
            sysMenus = sysMenuMapper.findMenuByUserId(Long.parseLong(userId));
            if (CollectionUtils.isEmpty(sysMenus)) {
                //说明该用户没有菜单
                return Collections.emptyList();
            }

            //转成json，存入redis
            redisTemplate.opsForValue().set(MenuConstant.MENU_PREFIX + userId, JSON.toJSONString(sysMenus), Duration.ofDays(7));
        } else {
            sysMenus = JSON.parseArray(menuStr, SysMenu.class);

        }
        //循环组装树菜单
        return loadMenuTree(sysMenus);
    }


    private List<SysMenu> loadMenuTree(List<SysMenu> sysMenus) {
        //拿到顶级菜单
        List<SysMenu> rootMenus = new ArrayList<>();
        sysMenus.forEach(menu -> {
            if ("0".equals(String.valueOf(menu.getParentId()))) {
                rootMenus.add(menu);
            }
        });

        //排序
        Collections.sort(rootMenus, order());

        //设置子节点
        rootMenus.forEach(genMenu -> {
            //获取根节点下所有子节点
            List<SysMenu> childList = getChild(genMenu.getMenuId(), sysMenus);
            genMenu.setList(childList);
        });
        return rootMenus;
    }

    private List<SysMenu> getChild(Long menuId, List<SysMenu> sysMenus) {

        //子菜单
        List<SysMenu> childList = new ArrayList<>();
        for (SysMenu menu : sysMenus) {
            //遍历所有节点，将所有菜单的父id与传过来的id比较
            //相等说明：为该根节点的子节点
            if (menuId.equals(menu.getParentId())) {
                childList.add(menu);
            }
        }

        //递归
        for (SysMenu menu : childList) {
            menu.setList(getChild(menu.getMenuId(), sysMenus));
        }

        //排序
        Collections.sort(childList, order());
        return childList;
    }


    private Comparator<SysMenu> order() {
        Comparator<SysMenu> comparator = new Comparator<SysMenu>() {
            @Override
            public int compare(SysMenu o1, SysMenu o2) {
                if (o1.getOrderNum().equals(o2.getOrderNum())) {
                    return o1.getOrderNum() - o2.getOrderNum();
                }
                return 0;
            }
        };
        return comparator;
    }
}
